<html>
<head>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="../resources/run-after-layout-and-paint.js"></script>
</head>
<body>

<select multiple id="menulist">
  <option selected>One</option>
  <option>Two</option>
  <option>Three</option>
  <option>Four</option>
</select>

<p id="description"></p>

<script>
// Wait until layout has settled to avoid notification spam.
async_test_after_layout_and_paint((testCase) => {
    const expectedNotifications = [
        'Focus',
        'SelectedChildrenChanged',
        'SelectedChildrenChanged',
        'ActiveDescendantChanged',
        'SelectedChildrenChanged',
        'ActiveDescendantChanged',
    ];
    let notificationReceivedIndex = 0;

    assert_own_property(window, 'accessibilityController');

    var menulist = document.getElementById("menulist");
    menulist.focus();
    window.accessibleMenulist = accessibilityController.focusedElement;
    window.accessibleOne = accessibleMenulist.childAtIndex(0).childAtIndex(0);
    window.accessibleTwo = accessibleMenulist.childAtIndex(0).childAtIndex(1);
    window.accessibleThree = accessibleMenulist.childAtIndex(0).childAtIndex(2);

    function listListener(notification) {
        assert_less_than(notificationReceivedIndex, expectedNotifications.length);
        assert_equals(notification, expectedNotifications[notificationReceivedIndex],
                      `Notification ${notificationReceivedIndex}`);
        ++notificationReceivedIndex;
    }
    accessibleMenulist.addNotificationListener(listListener);

    assert_true(accessibleOne.isSelected);
    assert_true(accessibleOne.isSelectedOptionActive);
    assert_false(accessibleTwo.isSelected);
    assert_false(accessibleTwo.isSelectedOptionActive);
    assert_false(accessibleThree.isSelected);
    assert_false(accessibleThree.isSelectedOptionActive);

    // Change the selected index by simulating a down arrow keydown event.
    eventSender.keyDown('ArrowDown', []);

    assert_false(accessibleOne.isSelected);
    assert_false(accessibleOne.isSelectedOptionActive);
    assert_true(accessibleTwo.isSelected);
    assert_true(accessibleTwo.isSelectedOptionActive);
    assert_false(accessibleThree.isSelected);
    assert_false(accessibleThree.isSelectedOptionActive);

    // Extend the selection by simulating a Shift + Down Arrow keydown event.
    eventSender.keyDown('ArrowDown', ['shiftKey']);

    assert_false(accessibleOne.isSelected);
    assert_false(accessibleOne.isSelectedOptionActive);
    assert_true(accessibleTwo.isSelected);
    assert_false(accessibleTwo.isSelectedOptionActive);
    assert_true(accessibleThree.isSelected);
    assert_true(accessibleThree.isSelectedOptionActive);

    // Make the test finish quickly whether we get the notification or not.
    window.setTimeout(testCase.step_func(() => {
        if (window.accessibilityController)
            accessibleMenulist.removeNotificationListener();
        assert_equals(notificationReceivedIndex, expectedNotifications.length,
                      'All notifications received');
        testCase.done();
    }), 10);
}, 'Navigating in a multiselect list updates selection and the active selected option and sends a notification');

</script>
</body>
</html>
